package org.tinygroup.dbcluster.sample.algorithm;

import com.google.common.collect.Range;
import org.tinygroup.dbcluster.algorithm.database.SingleKeyDatabaseShardingAlgorithm;
import org.tinygroup.dbcluster.base.ShardingValue;
import org.tinygroup.logger.Logger;
import org.tinygroup.logger.LoggerFactory;

import java.util.Collection;
import java.util.LinkedHashSet;

public final class ModuloDatabaseShardingAlgorithm implements SingleKeyDatabaseShardingAlgorithm<Integer> {
    private static final Logger logger = LoggerFactory.getLogger(ModuloDatabaseShardingAlgorithm.class);

    @Override
    public String doEqualSharding(final Collection<String> dataSourceNames, final ShardingValue<Integer> shardingValue) {
        for (String each : dataSourceNames) {
            Integer value = shardingValue.getValue();
            if (each.equalsIgnoreCase("biz_"+value % dataSourceNames.size() + "")) {
                logger.debugMessage("数据{0}被分配到{1}", value, each);
                return each;
            }
        }
        throw new IllegalArgumentException();
    }
    
    @Override
    public Collection<String> doInSharding(final Collection<String> dataSourceNames, final ShardingValue<Integer> shardingValue) {
        Collection<String> result = new LinkedHashSet<String>(dataSourceNames.size());
        for (Integer value : shardingValue.getValues()) {
            for (String dataSourceName : dataSourceNames) {
                if (dataSourceName.equalsIgnoreCase("biz_"+value % dataSourceNames.size() + "")) {
                    result.add(dataSourceName);
                }
            }
        }
        return result;
    }
    
    @Override
    public Collection<String> doBetweenSharding(final Collection<String> dataSourceNames, final ShardingValue<Integer> shardingValue) {
        Collection<String> result = new LinkedHashSet<String>(dataSourceNames.size());
        Range<Integer> range = shardingValue.getValueRange();
        for (Integer i = range.lowerEndpoint(); i <= range.upperEndpoint(); i++) {
            for (String each : dataSourceNames) {
                if (each.equalsIgnoreCase("biz_"+i % dataSourceNames.size() + "")) {
                    result.add(each);
                }
            }
        }
        return result;
    }
}
